/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.sales.hancadso.client.presenter;

import br.com.sales.generics.client.HanAbstractPresenter;
import br.com.sales.generics.client.components.autocomplete.widget.Autocomplete;
import br.com.sales.generics.client.components.scroll.HScroll;
import br.com.sales.generics.client.components.timepicker.HDateTimePicker;
import br.com.sales.generics.client.nametoken.NameTokens;
import br.com.sales.generics.client.presenter.events.EditRecordEvent;
import br.com.sales.generics.client.presenter.events.EditRecordHandler;
import br.com.sales.generics.client.request.HannaRequestCallback;
import br.com.sales.generics.client.utils.NumbersUtils;
import br.com.sales.hancadso.client.presenter.grid.HanCadSOGrid;
import br.com.sales.hancadso.client.presenter.values.ControlValues;
import br.com.sales.hancadso.client.service.HanCadSOService;
import br.com.sales.hancadso.client.view.HanCadSOResources;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ContentSlot;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author v
 */
public class HanCadSOPresenter
        extends HanAbstractPresenter<HanCadSOPresenter.Display, HanCadSOPresenter.MyProxy>
        implements HanCadSOUiHanlder, EditRecordHandler {

    @ContentSlot
    public static final GwtEvent.Type<RevealContentHandler<?>> HANCADSO_SLOT_TYPE = new GwtEvent.Type<>();
    private boolean isNewRecord;
    private boolean isEditing;
    @Inject
    private ControlValues controlValues;
    @Inject
    private HanCadSOService service;
    @Inject
    private HanCadSOGrid grid;
    private long sequenceEditing = 0;
    private int rowEditing;
    private final HTMLPanel panelGrid = new HTMLPanel("");

    @Inject
    public HanCadSOPresenter(EventBus eventBus, HanCadSOPresenter.Display view, HanCadSOPresenter.MyProxy proxy) {
        super(eventBus, view, proxy);
        getView().setUiHandlers(this);
    }

    @Override
    protected void onReveal() {
        super.onReveal();
        getView().setEnabled(isNewRecord);
        panelGrid.setVisible(false);
        getView().getFilterContainer().setVisible(false);
        panelGrid.add(grid);
        panelGrid.add(getView().getLoadingMessage());
        getView().setInSlot(HANCADSO_SLOT_TYPE, getView().getDetailPanel());
    }

    @Override
    protected void onBind() {
        super.onBind();
        getView().build();
        getEventBus().addHandler(EditRecordEvent.TYPE, this);
        getView().getCountEdit().addKeyPressHandler(new NumbersUtils.NumbersOnly());
    }

    @Override
    public void onClickNew(ClickEvent event) {
        if (!isNewRecord) {
            setValuesRecord(true);
        } else {
            if (Window.confirm("Deseja cancelar a edição atual?")) {
                setValuesRecord(true);
            }
        }
    }

    private void setValuesRecord(boolean newRecord) {
        isNewRecord = true;
        getView().getFilterContainer().setVisible(false);
        getView().setEnabled(isNewRecord);
        getView().controlVisibleButton(isNewRecord);
        if (newRecord) {
            controlValues.clearFields(getView());
            setDefaultValue();
        }
        getView().getRequesterComplete().setFocus(true);
        if (panelGrid.isVisible()) {
            getView().setInSlot(HANCADSO_SLOT_TYPE, getView().getDetailPanel());
            panelGrid.setVisible(false);
        }
    }

    @Override
    public void onClickAddItem(ClickEvent event) {
        if (!getView().isMandatorySubItem()) {
            int rowIndex = getView().getItemsGrid().getRowCount();
            addRow(getView().getNewProductComplete().getText(), rowIndex, 0);
            addRow(getView().getCountEdit().getText(), rowIndex, 1);
            addRow(new Image(HanCadSOResources.INSTANCE.edit()), rowIndex, 2);
            addRow(new Image(HanCadSOResources.INSTANCE.cancel()), rowIndex, 3);
            isEditing = false;
            cleaning();
        }
    }

    public void cleaning() {
        getView().getNewProductComplete().setValue(null);
        getView().getCountEdit().setValue(null);
    }

    @Override
    public void onClickCancel(ClickEvent event) {
        if (Window.confirm("Deseja cancelar?")) {
            controlValues.clearFields(getView());
            isNewRecord = false;
            getView().setEnabled(isNewRecord);
            getView().controlVisibleButton(isNewRecord);
            grid.setIsEditing(false);
            getView().isMandatory(isNewRecord);
        }
    }

    @Override
    public void onClickSave(ClickEvent event) {
        if (getView().getItemsGrid().getRowCount() < 0) {
            Window.alert("Nenhum item adicionado para essa solicitação!");
            return;
        }
        if (getView().isMandatory(isNewRecord)) {
            return;
        } 
        if (!getView().getNewProductComplete().isValidValue()
                || !getView().getRequesterComplete().isValidValue()) {
            Window.alert("Existem campos inválidos!\nFavor verificar.");
            return;
        }
        List<Map> productList = new ArrayList<>();
        for (int index = 0; index < getView().getItemsGrid().getRowCount(); index++) {
            if (index > 0) {
                Map itemSales = new LinkedHashMap();
                itemSales.put("ID_PRODUCT", getView().getNewProductComplete().getValueMap().get(getView().getItemsGrid().getText(index, 0)));
                itemSales.put("COUNT", getView().getItemsGrid().getText(index, 1));
                productList.add(itemSales);
            }
        }
        final Map params = new LinkedHashMap();
        params.put("SEQ", sequenceEditing);
        params.put("DATE", getView().getDateEdit().getText());
        params.put("NR_SEQ_PF", getView().getRequesterComplete().getValue());
        params.put("PRODUCTS", productList);

        service.insertNewItem(params, new HannaRequestCallback() {

            @Override
            public void onResponseReceived(Request request, Response response) {
                JSONObject record = new JSONObject(JsonUtils.safeEval(response.getText()));
                isNewRecord = false;
                getView().setEnabled(isNewRecord);
                getView().controlVisibleButton(isNewRecord);
                controlValues.clearFields(getView());
                sequenceEditing = 0;
                grid.addValueTogrid(record);
            }
        });
    }

    private void setDefaultValue() {
        DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy HH:mm:ss");
        getView().getDateEdit().setText(format.format(new Date(System.currentTimeMillis())));
    }

    @Override
    public void onClickGridDetail(ClickEvent event) {
        if (!panelGrid.isVisible()) {
            getView().setInSlot(HANCADSO_SLOT_TYPE, panelGrid.asWidget());
            panelGrid.setVisible(true);
            getView().getFilterContainer().setVisible(true);
            grid.update(getDataFilter());
        } else {
            getView().setInSlot(HANCADSO_SLOT_TYPE, getView().getDetailPanel().asWidget());
            panelGrid.setVisible(false);
            getView().getFilterContainer().setVisible(false);
        }
        getView().getFilterContainer().setVisible(panelGrid.isVisible());
    }

    @Override
    public void editRecorg(int row) {
        rowEditing = row;
        isEditing = true;
        getView().getNewProductComplete().setValue(getView().getItemsGrid().getText(row, 0));
        getView().getCountEdit().setValue(getView().getItemsGrid().getText(row, 1));
    }

    @Override
    public void addRow(Object value, int row, int cell) {
        if (isEditing) {
            Widget widget = getView().createCellWidget(value);
            getView().getItemsGrid().setWidget(rowEditing, cell, widget);
            getView().getItemsGrid().getCellFormatter().addStyleName(rowEditing, cell, "flextable-cell");
        } else {
            Widget widget = getView().createCellWidget(value);
            getView().getItemsGrid().setWidget(row, cell, widget);
            getView().getItemsGrid().getCellFormatter().addStyleName(row, cell, "flextable-cell");
            getView().getNewProductComplete().setFocus(true);
        }
    }

    @Override
    public void edit(JSONObject record) {
        sequenceEditing = Long.parseLong(toString(record.get("SEQ")));
        getView().getNewProductComplete().setValue(toString(record.get("DS_PRODUTO")), toString(record.get("NR_SEQ_PRODUTO")));
        getView().getRequesterComplete().setValue(toString(record.get("NM_PESSOA_FISICA")), toString(record.get("NR_SEQ_PESSOA")));
        getView().getCountEdit().setText(toString(record.get("QT_QUANTIDADE")));

        setValuesRecord(false);
    }

    private Map getDataFilter() {
        HashMap param = new HashMap();
        param.put("OPT_DATA", getSelectedOpt());
        param.put("DT_INICIO", getView().getInitialDate().getValueAsString() + " 00:00:00");
        param.put("DT_FIM", getView().getFinalDate().getValueAsString() + " 23:59:59");

        return param;

    }

    private String getSelectedOpt() {

        if (getView().getAprovacaoOpt().getValue()) {
            return "A";
        } else if (getView().getEncerramentoOpt().getValue()) {
            return "E";
        } else if (getView().getRegistroOpt().getValue()) {
            return "R";
        } else if (getView().getCancelamentoOpt().getValue()) {
            return "C";
        }
        return "N";
    }

    private String toString(JSONValue value) {
        if (value == null) {
            return "";
        }
        if (value instanceof JSONString) {
            return value.isString().stringValue();
        } else if (value instanceof JSONNumber) {
            return value.isNumber().toString();
        }
        return "";
    }

    @Override
    public void onClickRefresh(ClickEvent event) {
        grid.update(getDataFilter());
    }

    @ProxyStandard
    @NameToken(NameTokens.REGISTERNEWITEM)
    public interface MyProxy extends ProxyPlace<HanCadSOPresenter> {
    }

    public interface Display extends View, HasUiHandlers<HanCadSOUiHanlder> {

        void build();

        boolean isMandatory(Boolean isEditing);

        boolean isMandatorySubItem();

        void setEnabled(boolean isNewrecord);

        void controlVisibleButton(boolean isNewrecord);

        void showLoading(boolean show);

        Image getLoadingMessage();

        HTMLPanel getDetailPanel();

        TextBox getDateEdit();

        void clearGrid();

        TextBox getCountEdit();

        Autocomplete getRequesterComplete();

        Autocomplete getNewProductComplete();

        Widget createCellWidget(Object cellObject);

        FlexTable getItemsGrid();

        HScroll getMainContentScrollPanel();

        HDateTimePicker getInitialDate();

        HDateTimePicker getFinalDate();

        HTMLPanel getRadioContainer();

        HTMLPanel getFilterContainer();

        RadioButton getAprovacaoOpt();

        RadioButton getEncerramentoOpt();

        RadioButton getRegistroOpt();

        RadioButton getCancelamentoOpt();

        RadioButton getNaoFiltrarOpt();

    }
}
